package com.mustafaiev.tair.cts.dao.jpa;

import java.util.List;

import org.apache.log4j.Logger;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.mustafaiev.tair.cts.dao.IPayerDAO;
import com.mustafaiev.tair.cts.exeption.DataNotRemovedException;
import com.mustafaiev.tair.cts.exeption.DataNotRetrievedException;
import com.mustafaiev.tair.cts.exeption.DataNotStoredException;
import com.mustafaiev.tair.cts.model.Payer;

/**
 * Payer Data Access Object
 * 
 * @author tair
 * 
 */
@Repository(value = "payerDao")
@Transactional
public class PayerDAO implements IPayerDAO {

	private static final String DELETE_FROM_PAYER_WHERE_ID = "delete from Payer where id=?";

	private static final String SELECT_ALL_FROM_PAYER = "from Payer";

	private static final String SELECT_PAYER_BY_EMAIL = "from Payer where email=?";

	private static final String SELECT_ACTIVE_PAYER_BY_EMAIL = "from Payer where email=? and ";

	private static final Logger LOGGER = Logger.getLogger(PayerDAO.class);

	private HibernateTemplate hibernateTemplate;

	@Autowired
	public void setHibernateTemplate(final HibernateTemplate hibernateTemplate) {
		this.hibernateTemplate = hibernateTemplate;
	}

	@Override
	public void doSave(final Payer t) throws DataNotStoredException {
		final Transaction transaction = getTransaction();
		try {
			transaction.begin();
			this.hibernateTemplate.save(t);
			transaction.commit();
		} catch (final HibernateException e) {
			transaction.rollback();
			LOGGER.error(e);
			throw new DataNotStoredException(
					"Payer was not stored for some reason", e);
		}
	}

	@Override
	public Payer retrievePayer(final Long payerId) {
		Payer payer = null;
		try {
			payer = (Payer) this.hibernateTemplate.get(Payer.class, payerId);
		} catch (final HibernateException e) {
			LOGGER.error(e);
		}
		return payer;
	}

	@Override
	public void deleteBatch(final List<Payer> payersToDelete)
			throws DataNotRemovedException {
		final Session session = this.hibernateTemplate.getSessionFactory()
				.openSession();
		final Transaction transaction = getTransaction();
		try {
			transaction.begin();
			for (final Payer payer : payersToDelete) {
				session.createQuery(DELETE_FROM_PAYER_WHERE_ID)
						.setLong(0, payer.getId()).executeUpdate();
			}
			transaction.commit();
		} catch (final HibernateException e) {
			LOGGER.error(e);
			throw new DataNotRemovedException(
					"Payer was not deleted for some reason", e);
		}
	}

	@Override
	public void doUpdate(final Payer t) throws DataNotStoredException {

	}

	@Override
	public List<Payer> retrieveActivePayers() throws DataNotRetrievedException {
		final Session session = this.hibernateTemplate.getSessionFactory()
				.openSession();
		List<Payer> payers = null;
		try {
			payers = session.createQuery(SELECT_ALL_FROM_PAYER).list();
		} catch (final HibernateException e) {
			LOGGER.error(e);
		}
		return payers;
	}

	@Override
	public List<Payer> retrieveActivePayersForGroup(final Long goupKey)
			throws DataNotRetrievedException {
		return null;
	}

	@Override
	public Payer findActiveByEmail(final String email)
			throws DataNotRetrievedException {
		final Session session = this.hibernateTemplate.getSessionFactory()
				.openSession();
		Payer payer = null;
		try {
			final Query query = session.createQuery(SELECT_PAYER_BY_EMAIL);
			query.setString(0, email);
			payer = (Payer) query.uniqueResult();
		} catch (final HibernateException e) {
			LOGGER.error(e);
		}
		return payer;
	}

	@Override
	@Transactional
	public Payer findByEmail(final String email)
			throws DataNotRetrievedException {
		final Session session = this.hibernateTemplate.getSessionFactory()
				.openSession();
		Payer payer = null;
		try {
			final Query query = session.createQuery(SELECT_PAYER_BY_EMAIL);
			query.setString(0, email);
			payer = (Payer) query.uniqueResult();
		} catch (final HibernateException e) {
			LOGGER.error(e);
		}
		return payer;
	}

	@Override
	public Payer retrieveByEmail(final String email)
			throws DataNotRetrievedException {
		return null;
	}

	@Override
	public void resetPassword(final Payer payer, final String password)
			throws DataNotStoredException {

	}

	@Override
	public void doDelete(final Payer t) throws DataNotRemovedException {
		// TODO Auto-generated method stub

	}

	@Override
	public void doDeleteById(final Long id) throws DataNotRemovedException {
		// TODO Auto-generated method stub

	}

	private Transaction getTransaction() {
		return this.hibernateTemplate.getSessionFactory().openSession()
				.getTransaction();
	}

}
